package repository

import (
	"errors"
	"fmt"
	"github.com/gccai/write_helper/model"
	"github.com/gccai/write_helper/query"
	"github.com/gccai/write_helper/utils"
	"github.com/jinzhu/gorm"
	"time"
)

type BookRepository struct {
	DB *gorm.DB
}

type BookRepositoryInterface interface {
	Add(book *model.Book) (newBook *model.Book, err error)
	Delete(bookName string, userId string) (b bool, err error)
	Edit(book *model.Book) (b bool, err error)
	UpdateChapter(book *model.Book) (bool, error)
	GetOneBook(book *model.Book) (*model.Book, error)
	GetTotal(writeName string) (total int, err error)
	BookList(req *query.ListQuery, userId string) (books []*model.Book, err error)
	ExistByBookName(userid, bookName string) *model.Book
	ExistAndDeleted(book *model.Book) *model.Book
	ExistByUserId(userId string) []*model.Book
	//GetChapterCount(book *model.Book) (int64, error)
}

func (b BookRepository) Add(book *model.Book) (*model.Book, error) {
	if err := b.DB.Create(book).Error; err != nil {
		return nil, fmt.Errorf("书籍添加失败")
	}
	return book, nil
}

func (b BookRepository) Delete(bookName string, userId string) (bool, error) {
	err := b.DB.Model(&model.Book{}).Where("book_name = ? and user_id = ?", bookName, userId).Updates(map[string]interface{}{
		"is_deleted": true,
		"update_at":  time.Now(),
	}).Error
	if err != nil {
		return false, err
	}
	return true, nil
}

func (b BookRepository) Edit(book *model.Book) (bool, error) {
	book.UpdateAt = time.Now()
	if err := b.DB.Model(book).Where("user_id = ? and book_name = ?", book.UserId, book.BookName).Updates(map[string]interface{}{
		// "book_name":          book.BookName,
		"brief_introduction": book.BriefIntroduction,
		"story_core":         book.StoryCore,
		"writer_name":         book.WriterName,
		"update_at":          book.UpdateAt,
		"is_deleted":         book.IsDeleted,
		//"chapter_count":      book.ChapterCount,
	}).Error; err != nil {
		return false, err
	}
	return true, nil
}
func (b BookRepository) UpdateChapter(book *model.Book) (bool, error) {
	if err := b.DB.Model(book).Where("user_id = ? and book_name = ? and is_deleted = ?",
		book.UserId, book.BookName, false).Update(map[string]interface{}{
		"chapter_count": book.ChapterCount,
	}).Error; err != nil {
		return false, err
	}
	return true, nil
}

// 根据书名
func (b BookRepository) GetOneBook(book *model.Book) (*model.Book, error) {
	var fbook model.Book
	res := b.DB.Where("user_id = ? and book_name = ?",book.UserId, book.BookName).Find(&fbook)
	if res.RowsAffected > 0 {
		return &fbook, nil
	}
	return nil, errors.New("查无此书，欢迎创建")
}

// 根据作者
func (b BookRepository) GetTotal(writeName string) (total int, err error) {

	err = b.DB.Where("writer_name = ? and is_deleted = ?", writeName, false).Find(&model.Book{}).Count(&total).Error
	if err != nil {
		return total, err
	}
	return total, nil

}

func (b BookRepository) BookList(req *query.ListQuery, userId string) (books []*model.Book, err error) {
	limit, offset := utils.Page(req.PageSize, req.Page)
	// fmt.Println("this?")
	if err = b.DB.Where("user_id = ? and is_deleted = ?", userId, false).Limit(limit).Offset(offset).Find(&books).Error; err != nil {
		fmt.Println(err.Error())
		return nil, err
	}
	
	return books, nil
}

func (b BookRepository) ExistByBookName(userId, bookName string) *model.Book {
	var book model.Book
	if err := b.DB.Where("user_id = ? and book_name = ?", bookName).Find(&book).Error; err != nil {
		return nil
	}
	return &book
}

func (b BookRepository) ExistAndDeleted(book *model.Book) *model.Book {
	var dbook model.Book
	if err := b.DB.Where("user_id = ? and book_name = ? and is_deleted = ? ", book.UserId, book.BookName, false).Find(&dbook).Error; err != nil {
		return nil
	}
	return &dbook
}

func (b BookRepository) ExistByUserId(userId string) []*model.Book {
	var books []*model.Book
	err := b.DB.Where("user_id = ? and is_deleted = ?", userId, false).Find(&books).Error
	if err != nil {
		return nil
	}
	return books
}

//func (b BookRepository) GetChapterCount(book *model.Book) (int64, error) {
//	var bo model.Book
//	if err := b.DB.Where("user_id = ? and book_name = ? and is_deleted = ?", book.UserId, book.BookName, false).Find(&bo).Error; err != nil {
//		return -1, err
//	}
//	return bo.ChapterCount, nil
//}
